﻿using GCC.APIContainer.Auth.Attributes;
using GCC.APIContainer.Utilities;
using GCC.Container.Abstracts;
using GCC.Container.Models;
using GCCGrpc.FileServer;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.DeviceServer.ApiModels.DeviceType;
using System.DeviceServer.Models;
using System.Drawing;

namespace System.DeviceServer
{
    [ApiController]
    [Route("[controller]")]
    public class DeviceTypeServer : GCCAPIControllerBase
    {
        public DeviceTypeServer(AbsGCCContext context) : base(context)
        {
        }

        [HttpGet("devtypes")]
       // [GCCAuth(allowOffline: true, roles: new string[] { "admin" })]
        public DataResponse<List<getAllDevicesTypeResponse>> GetAllDevicesType([FromQuery] getAllDevicesTypeRequest request)
        {
           
            var dbres = AbsEntrance.DBManager!.LocalDB!.Select<DevType>()
                .Count(out var count)
                .Page(request.PageIndex ?? 1, request.PageSize)
                .ToList();
            return HandleData(dbres.Select(item => new getAllDevicesTypeResponse()
            {
                TypeID = item.TypeID.ToString(),
                TypeName = item.TypeName,
                TypeICON = item.TypeICON.ToString(),
                PointName = item.PointName
            }).ToList(), count);
        }

        [HttpGet("devtype/id/{id}")]
        //[GCCAuth(allowOffline: true, roles: new string[] { "admin" })]
        public DataResponse<GetDeviceTypeByIDResponse> GetDeviceTypeByID([FromRoute] long id)
        {
            var dbres = GCCEntrance.DBManager!.LocalDB!.Select<DevType>()
                .Where(item => item.TypeID == id).First();

            if (dbres == null)
            {
                return IllegalRequest<GetDeviceTypeByIDResponse>();
            }
            var res = new GetDeviceTypeByIDResponse();
            res.TypeID = dbres.TypeID.ToString();
            res.TypeName = dbres.TypeName;
            res.TypeICON = dbres.TypeICON.ToString();
            res.PointName = dbres.PointName;
            return HandleData(res);
        }

        [HttpPost("devtype/icon")]
        //[GCCAuth(allowOffline: false, roles: new string[] { "admin" })]
        public DataResponse<AddTypeIconResponse> AddTypeIcon(IFormFile file)
        { 
            if (file is null)
            {
                return InvalidParameter<AddTypeIconResponse>();
            }
            var fileServerHost = GCCContext.GetConfigByPath(new string[] { GCCContext.PointName ?? "", "FileServer" });
            var fileFolderPath = Path.Combine(AppContext.BaseDirectory, Guid.NewGuid().ToString("N"));
            var filePath = Path.Combine(fileFolderPath, file.FileName);

           
            
            _ = Directory.CreateDirectory(fileFolderPath);
            {
                using var fs = System.IO.File.Open(filePath, FileMode.CreateNew, FileAccess.ReadWrite);
                file.CopyTo(fs);
                fs.Flush();
                fs.Close();
            }
            
           GRPCCreateBigFileResponse? res = null;
            foreach (var item in System.FileServer.Client.Manager.GRPCCreateBigFile(fileServerHost, filePath, GCCContext.EventID ?? ""))
            {
                res = item.res;
            }
            if (res is null)
            { 
                return InvalidParameter<AddTypeIconResponse>();
            } 

            var ret = new AddTypeIconResponse();
            ret.ID = res.ID.ToString();
            ret.PointName = res.CurrentSavePoint;
            return HandleData(ret);
        }

        [HttpPost("devtypes")]
        //[GCCAuth(allowOffline: false, roles: new string[] { "admin" })]
        public DataResponse<bool> AddDeviceType([FromBody] List<AddDeviceTypeRequest> requestList)
        {
            if (requestList is null)
            { 
                return IllegalRequest<bool>();
            }

            if (requestList.Count == 0)
            {
                return IllegalRequest<bool>();
            }

            Console.WriteLine("\nitem count:{0}\n", requestList.Count);
            var items = new List<DevType>();
            foreach (var item in requestList)
            {
                if (string.IsNullOrWhiteSpace(item.TypeName) ||
                        string.IsNullOrWhiteSpace(item.PointName) || string.IsNullOrWhiteSpace(item.TypeICON))
                {
                    return InvalidParameter<bool>();
                }
                items.Add(new DevType()
                {
                    TypeID = LuanNiao.Core.IDGen.GetInstance().NextId(),
                    TypeName = item.TypeName,
                    TypeICON = long.Parse(item.TypeICON),
                    PointName = item.PointName,
                });
            }
            bool saveRes;
            try
            {
                if (GCCEntrance.DBManager!.LocalDB!.Insert(items).ExecuteAffrows() != items.Count)
                {
                    throw new Exception();
                }
            }
            catch (Exception)
            {
                throw new Exception();
            }
            _ = GCCContext.Remove("DevType");
            saveRes = true;
            return HandleData(saveRes);
        }

        [HttpPut("devtype/id/{id}")]
        //[GCCAuth(allowOffline: false, roles: new string[] { "admin" })]
        public DataResponse<bool> UpdateDevicesType([FromBody] UpdateDeviceTypeRequest request, long id)
        {
            if (request is null || string.IsNullOrWhiteSpace(request.PointName) 
                || string.IsNullOrWhiteSpace(request.TypeName))
            { 
                return InvalidParameter<bool>();
            }
            var res = GCCEntrance.DBManager!.LocalDB!.Update<DevType>()
                .Set(a => a.TypeName, request.TypeName)
                .Set(a => a.TypeICON, long.Parse(request.TypeICON))
                .Set(a => a.PointName, request.PointName)
                .Where(a => a.TypeID == id)
                .ExecuteAffrows() == 1;

            if (res)
            {
                _ = GCCContext.Remove("DevType");
            }
            return HandleData(res);
        }
    }
}
